<template>
  <div class="users">
    <!-- 1、面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 2、卡片： 主要列表区域 -->
    <el-card>
        <!-- 第一行：搜索框和按钮 -->
        <el-row :gutter="10">
            <el-col :span="10">
              <!-- Clearable属性是指输入内容可清空，点击清空触发一个事件 clear -->
                <el-input placeholder="请输入搜索内容" v-model="queryInfo.query" @clear="clearAndsearch" :clearable="true">
                    <el-button slot="append" icon="el-icon-search" @click="searchUsers"></el-button>
                </el-input>
            </el-col>
            <el-col :span="14">
                <el-button type="primary" @click="addUsersDialogIsVisible=true">添加用户</el-button>
            </el-col>
        </el-row>
        <!-- 第二行： 用户列表信息 :  可以使用组件库中的el-table组件  
            我也可以使用学过的v-for循环去便遍历:
                1.0 v-for遍历很方便，就不用使用slot-scope插槽去获取当前行的数据了。
        -->
        <el-table :data="userList" border style="width: 100%">
          <!-- 索引列 -->
          <el-table-column type="index" width="50px"></el-table-column>
          <!-- 有数据源的4列 -->
          <el-table-column prop="username" label="姓名"></el-table-column>
          <el-table-column prop="email" label="邮箱"></el-table-column>
          <el-table-column prop="mobile" label="电话"></el-table-column>
          <el-table-column prop="role_name" label="角色"></el-table-column>
          <!-- 状态列 -->
          <el-table-column label="状态">
            <template slot-scope="scope">
              <!-- {{scope.row}} :是指这一行的所有数据 -->
                <el-switch v-model="scope.row.mg_state" @change="updateUserState(scope.row)"></el-switch>
            </template>
          </el-table-column>
          <!-- 操作列 -->
          <el-table-column label="操作" width="200px">
              <template slot-scope="scope">
                <el-button type="primary" icon="el-icon-edit" @click="updateUsersDialog(scope.row.id)" size="small"></el-button>
                <el-button type="danger" icon="el-icon-delete" @click="deleteUsers(scope.row.id)" size="small"></el-button>
                <!-- 分配角色按钮 -->
                <el-tooltip effect="dark" content="角色分配" placement="top" :enterable="false">
                  <el-button type="warning" icon="el-icon-setting" @click="setUsersDialog(scope.row)" size="small"></el-button>
                </el-tooltip>
              </template>
          </el-table-column>
        </el-table>

        <!-- 第三行 :分页区域 ： 把参数填进去，自动根据用户列表数据根据下面的参数分为几页，这个分页组件很好用。 -->
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="queryInfo.pagenum"
          :page-sizes="[1, 3, 5, 8,10,15]"
          :page-size="queryInfo.pagesize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total">
        </el-pagination>
    </el-card>


    <!-- 3、对话框 -->             
    <!--  1.0 添加用户的对话框：:visible.sync的值为true表示显示，false表示不显示对话框 -->
    <el-dialog 
        title="添加用户信息" 
        :visible.sync="addUsersDialogIsVisible" 
        width="400px"
        @close="()=>{this.$refs.addUserFormRef.resetFields();}">
        <!-- 对话框关闭时触发close的事件函数： 重置表单：关闭对话框时和点击充值按钮时 -->
        <!-- 表单 -->
        <el-form :model="addUserObj" :rules="addUserFormRules" ref="addUserFormRef">
            <el-form-item label="用户名:" label-width="70px" prop="username">
                <el-input v-model="addUserObj.username"></el-input>
            </el-form-item>
            <el-form-item label="密 码:" label-width="70px" prop="password">
                <el-input v-model="addUserObj.password"></el-input>
            </el-form-item>
            <el-form-item label="邮 箱:" label-width="70px" prop="email">
                <el-input v-model="addUserObj.email"></el-input>
            </el-form-item>
            <el-form-item label="电 话:" label-width="70px" prop="mobile">
                <el-input v-model="addUserObj.mobile"></el-input>
            </el-form-item>
        </el-form>
        <!-- 按钮 -->
        <div slot="footer">
            <el-button @click="addUsersDialogIsVisible = false">取 消</el-button>
            <el-button type="primary" @click="addUsers">添 加</el-button>
            <el-button type="info" @click="()=>{this.$refs.addUserFormRef.resetFields();}">重置</el-button>
        </div>
    </el-dialog>
    
    <!-- 2.0 修改用户信息对话框 -->
    <el-dialog 
      title="修改用户信息" 
      :visible.sync="updateUsersDialogIsVisible" 
      width="400px"
      @close="()=>{this.$refs.updateUserFormRef.resetFields();}">
      <!-- 对话框关闭时触发close的事件函数： 重置表单：关闭对话框时和点击充值按钮时 -->
      <!-- 表单 -->
      <el-form :model="updateUserObj" :rules="addUserFormRules" ref="updateUserFormRef">
          <el-form-item label="用户名:" label-width="70px">
              <el-input v-model="updateUserObj.username" disabled></el-input>
          </el-form-item>
          <el-form-item label="邮 箱:" label-width="70px" prop="email">
              <el-input v-model="updateUserObj.email"></el-input>
          </el-form-item>
          <el-form-item label="电 话:" label-width="70px" prop="mobile">
              <el-input v-model="updateUserObj.mobile"></el-input>
          </el-form-item>
      </el-form>
      <!-- 按钮 -->
      <div slot="footer">
          <el-button @click="updateUsersDialogIsVisible = false">取 消</el-button>
          <el-button type="primary" @click="updateUsers">提 交</el-button>
      </div>
    </el-dialog>

    <!-- 3.0 为用户分配角色的对话框  -->
    <el-dialog
      title="分配角色"
      :visible.sync="setUsersDialogIsVisible"
      width="500px"
       @close="CloseDialog"
    >
      <div style="margin:5px 0px">当前用户：{{userInfo.username}}</div>
      <div style="margin:5px 0px">当前角色：{{userInfo.role_name}}</div>
      <!-- 选择框 -->
      <p  style="margin:5px 0px">分配角色:
        <el-select v-model="selectedRolesId" placeholder="请选择">
          <el-option
            v-for="item in rolesList"
            :key="item.id"
            :label="item.roleName"
            :value="item.id">
            <!-- :value表示实际选中的值，记录到selectedRolesId  ； :label表示选中的文字 -->
          </el-option>
      </el-select>
      </p>
      <!-- 按钮 -->
      <div slot="footer">
        <el-button @click="setUsersDialogIsVisible = false">取 消</el-button>
        <el-button type="primary" @click="setUsers">分 配</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
    data(){
      // 自定义电话号码验证规则
      const checkMobile = (rule, value, cb) => {
        let reg = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;
        if (reg.test(value))  //返回true
          cb();
        else
          cb(new Error('电话号码格式不正确'));
      }
      // 自定义电话号码验证规则
      const checkEmail= (rule, value, cb) => {
        let reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
        if (reg.test(value))  //返回true
          cb();
        else
          cb(new Error('邮箱格式不正确'));
      }
      
       return {
        // 获取用户列表的对象
        queryInfo:{
          // 查询参数
          query:'',
          // 当前所处页码
          pagenum:1,
          // 每页显示条数
          pagesize:3,
        },
        // 用户列表数据  : 根据筛选条件，筛选出来的用户数据
        userList:[
          // create_time: 1486720211,
          // email: "adsfad@qq.com",
          // id: 500,
          // mg_state: true,
          // mobile: "12345678",
          // role_name: "超级管理员",
          // username: "admin",
        ],
        // 查询到的用户个数
        total:0,

        // 添加用户的对话框是否显示
        addUsersDialogIsVisible:false,
        // 添加用户时的对象参数
        addUserObj:{
          username: "",
          password: "",
          email: "",
          mobile: "",
        },
        // 添加用户的对话框中的表单验证
        addUserFormRules:{
            // 验证用户名的规则,trigger表示触发的条件  blur：失去焦点
            username:[
                { required: true, message: '用户名不能为空', trigger: 'blur' },
                { min:2, max: 10, message: '长度在2 到 10 个字符', trigger: 'blur' }
            ],
            // 验证密码的规则
            password:[
                { required: true, message: '密码不能为空', trigger: 'blur' },
                { min: 6, max: 16, message: '长度在6 到 16 个字符', trigger: 'blur' }
            ],
            //邮箱、电话可以为空
            email:[
                { required: true, message: '请输入邮箱', trigger: 'blur' },
                { validator: checkEmail, trigger: 'blur' }
            ],
            mobile:[
                { required: true, message: '请输入电话号码', trigger: 'blur' },
                { validator: checkMobile, trigger: 'blur' }
            ]
        },

        // 修改用户的对话框是否显示
        updateUsersDialogIsVisible:false,
         // 修改用户时的对象参数 ： 点击事件==》根据id获取用户信息，存放到输入框
        updateUserObj:{
          id:0,
          username: "",
          email: "",
          mobile: "",
        },

        // 为用户分配角色的对话框是否显示
        setUsersDialogIsVisible:false,
        // 当前正在分配角色的用户
        userInfo:"",
        // 选中的角色名称对应的id
        selectedRolesId:'',
        // 角色列表
        rolesList:[
          // {
          //   children: Array(5),
          //   id: 30,
          //   roleDesc: "技术负责人",
          //   roleName: "主管",
          // },
        ],
       }
    },
    methods:{
        // 获取用户列表
        async getUserList(){
            const res = await this.$http.get('users', {params : this.queryInfo});
            if(res.data.meta.status==200)
            {
               this.userList=res.data.data.users;
               this.total=res.data.data.total;
               console.log("用户列表： ",this.userList);
            }
        },

        // 获取角色列表
        async getRolesList(){
            const res = await this.$http.get('roles');
            if(res.data.meta.status==200)
            {
               this.rolesList=res.data.data;
               console.log("所有角色列表： ",res.data.data);
            }
        },

        // 添加用户
        addUsers(){
            /* 点击添加按钮时，还要进行一遍预验证，
                1.0 验证时要是表单元素不正确，就不继续向下执行，
                2.0 所有表单元素验证都正确，向下执行代码--就提交请求
          */ 
            // 拿到整个表单对象，调用其函数
            this.$refs.addUserFormRef.validate(async valid=>{
              if(!valid) return;

              // 整个表单域预校验通过
              const res = await this.$http.post('users',this.addUserObj);

              if(res.data.meta.status!==201)  return this.$message.error('添加用户失败！');
              
              this.addUsersDialogIsVisible = false;
              this.$message.success('添加用户成功！');
              this.getUserList();
            })
        },
        // 修改用户的对话框
        updateUsersDialog(id){
            this.updateUsersDialogIsVisible=true;
            // 根据id查找到对应用户信息
            this.userList.forEach(item=>{
              if(item.id==id){
                this.updateUserObj.id=item.id;
                this.updateUserObj.username=item.username;
                this.updateUserObj.mobile=item.mobile;
                this.updateUserObj.email=item.email;
              }
            })
        },
        // 修改用户--提交按钮
        async updateUsers(){
            this.$refs.updateUserFormRef.validate(async valid=>{
              if(!valid) return;

              // 整个表单校验通过
              const res = await this.$http.put('users/'+this.updateUserObj.id,{
                // 用户的id必须是数字
                id:this.updateUserObj.id,
                email:this.updateUserObj.email,
                mobile:this.updateUserObj.mobile
              });

              // console.log(res.data);
              if(res.data.meta.status!==200)  return this.$message.error('修改用户失败！');
              
              this.updateUsersDialogIsVisible = false;
              this.$message.success('修改用户成功！');
              this.getUserList();
            })
        },

        //删除用户
        async deleteUsers(id){
            let str = await this.$messagebox.confirm('此操作将永久删除该用户, 是否继续?', '提示', {
              confirmButtonText: '确定',  //返回值为 confirm
              cancelButtonText: '取消',   //返回值为 cancel
              type: 'warning'
            }).catch(() => this.$message({ type: 'info', message: '已取消删除'}) );

            // 当用户点击取消时会报错，用catch捕获到错误去执行对应的事件

            //如果用户选择确定==》admin不允许删除--删除失败 / 其他用户允许删除--删除成功
            if(str == 'confirm'){
              const res = await this.$http.delete('users/'+id);
              if(res.data.meta.status!==200)
                  return this.$message({ type: 'error', message: '删除用户失败!'});

              this.$message({ type: 'success', message: '删除用户成功!'});
              this.getUserList();
            }
        },

        //分配角色的对话框
        setUsersDialog(user){
            this.userInfo = user;
            // console.log('当前用户：',this.userInfo);
            this.setUsersDialogIsVisible=true;
            // 获取角色列表
            this.getRolesList();
        },
        // 分配角色
        async setUsers(){
            if(!this.selectedRolesId) return this.$message.error("请选择要分配的角色!");
            const res = await this.$http.put(`users/${this.userInfo.id}/role`,{ rid : this.selectedRolesId});

            // console.log('选中的角色的id:',this.selectedRolesId);
            // console.log('分配角色：',res.data);

            if(res.data.meta.status!==200) return this.$message.error("分配角色失败！");
            this.$message.success("分配角色成功！");
            this.getUserList();
            this.setUsersDialogIsVisible=false;
        },
        // 关闭分配角色对话框时触发
        CloseDialog(){
          this.userInfo={};
          this.selectedRolesId="";
        },

        handleSizeChange(newSize){
          // 每页显示数据条数的切换pagesize
          this.queryInfo.pagesize=newSize;
          this.getUserList();
        },
        handleCurrentChange(newPage){
          // 当前所处页码切换
          this.queryInfo.pagenum=newPage;
          this.getUserList();
        },
        //点击switch开关修改用户状态
        async updateUserState(userItemInfo){
          // 把双向绑定的已经修改状态后的这个用户信息执行修改请求操作
          const res = await this.$http.put(
            'users/'+userItemInfo.id+'/state/'+userItemInfo.mg_state,
            userItemInfo
          );
          console.log(userItemInfo.role_name,"- 用户状态发生改变：",res.data);
        },
        // 点击搜索图标，按照搜索关键字显示列表信息,  关键字匹配是否在属性姓名中
        searchUsers(){
          this.getUserList();
        },
        // 搜索输入框的清空事件：点击清空后实现内容清空且再次显示全部用户列表信息(搜索关键字为空时的用户信息)
        clearAndsearch(){
          this.getUserList();
        }
    },
    created(){
        this.getUserList();
    },
}
</script>

<style scoped>
  .el-card {
    width: 100%;
    margin-top: 10px;
    box-shadow: 0px 0px 3px skyblue;
    background-color: #fff;
  }
  /* 输入框和按钮所在盒子的宽度 */
  .el-table{
    margin-top: 15px;
    font-size: 13px;
  }
  .el-pagination{
    margin-top: 10px;
  }
</style>